package segmented_control.widget.custom.ohos.com.segmentedcontrol.utils;


import ohos.agp.colors.RgbColor;
import ohos.agp.components.element.ShapeElement;

import segmented_control.widget.custom.ohos.com.segmentedcontrol.item_row_column.SegmentBackgroundType;
import segmented_control.widget.custom.ohos.com.segmentedcontrol.item_row_column.SegmentViewHolder;

/**
 * Created by Robert Apikyan on 9/8/2017.
 */

public class Utils {
    /**
     * lazy
     *
     * @param nullable nullable
     * @param nonNull nonNull
     * @param <T> t
     * @return t
     */
    public static <T> T lazy(T nullable, T nonNull) {
        if (nullable == null) {
            nullable = nonNull;
        }
        return nullable;
    }

    /**
     * Utility method, use to define segment background type
     *
     * @param absolutePosition Segment absolute position from {@link SegmentViewHolder#getAbsolutePosition()}
     * @param columnCount from {@link SegmentViewHolder#getColumnCount()}
     * @param size from {@link SegmentViewHolder#getCurrentSize()}
     * @return {@link SegmentBackgroundType}
     */
    @SegmentBackgroundType
    public static int defineSegmentBackground(int absolutePosition, int columnCount,int size) {

        // if only one item
        if (size == 1) {
            return SegmentBackgroundType.SINGLE_BG;
        }

        // if one column
        if (columnCount == 1) {
            // for first
            if (absolutePosition == 0) {
                return SegmentBackgroundType.TOP_SINGLE_BG;
            }

            // for last
            if (absolutePosition == size - 1) {
                return SegmentBackgroundType.BOTTOM_SINGLE_BG;
            }
        }

        // if not one column, but one row
        if (size <= columnCount) {
            if (absolutePosition == 0) {
                return SegmentBackgroundType.TOP_LEFT_SINGLE_BG;
            }

            if (absolutePosition == size - 1) {
                return SegmentBackgroundType.TOP_RIGHT_SINGLE_BG;
            }
        }

        // if not one column and multi row
        if (absolutePosition == 0) {
            return SegmentBackgroundType.TOP_LEFT_BG;
        }

        if (absolutePosition == columnCount - 1) {
            return SegmentBackgroundType.TOP_RIGHT_BG;
        }

        int notCompletedRowItemsCount = size % columnCount;

        int completeRowsItemsCount = size - notCompletedRowItemsCount;

        if (notCompletedRowItemsCount == 1 && absolutePosition == completeRowsItemsCount) {
            return SegmentBackgroundType.BOTTOM_SINGLE_BG;
        }

        if (notCompletedRowItemsCount == 0) {
            if (absolutePosition == size - columnCount) {
                return SegmentBackgroundType.BOTTOM_LEFT_BG;
            }
            if (absolutePosition == size - 1) {
                return SegmentBackgroundType.BOTTOM_RIGHT_BG;
            }
        } else if (notCompletedRowItemsCount > 0) {
            if (absolutePosition == size - notCompletedRowItemsCount) {
                return SegmentBackgroundType.BOTTOM_LEFT_BG;
            }
            if (absolutePosition == size - 1) {
                return SegmentBackgroundType.BOTTOM_RIGHT_BG;
            }
        }

        return SegmentBackgroundType.MIDDLE_BG;
    }

    /**
     * Use to define segment corner radius
     *
     * @param absolutePosition Segment absolute position from {@link SegmentViewHolder#getAbsolutePosition()}
     * @param columnCount from {@link SegmentViewHolder#getColumnCount()}
     * @param size from {@link SegmentViewHolder#getCurrentSize()}
     * @param topLeftRadius from {@link SegmentViewHolder#getTopLeftRadius()}
     * @param topRightRadius from {@link SegmentViewHolder#getTopRightRadius()} ()}
     * @param bottomRightRadius from {@link SegmentViewHolder#getBottomRightRadius()}
     * @param bottomLeftRadius from  {@link SegmentViewHolder#getBottomLeftRadius()}
     * @return float[] corners radius,
     */
    public static float[] defineRadiusForPosition(int absolutePosition,int columnCount,int size,int topLeftRadius, int topRightRadius, int bottomRightRadius, int bottomLeftRadius) {
        @SegmentBackgroundType
        int bgType = defineSegmentBackground(absolutePosition, columnCount, size);

        switch (bgType) {

            case SegmentBackgroundType.BOTTOM_LEFT_BG:
                return createRadius(0, 0, 0, bottomLeftRadius);

            case SegmentBackgroundType.BOTTOM_RIGHT_BG:
                return createRadius(0, 0, bottomRightRadius, 0);

            case SegmentBackgroundType.BOTTOM_SINGLE_BG:
                return createRadius(0, 0, bottomRightRadius, bottomLeftRadius);

            case SegmentBackgroundType.MIDDLE_BG:
                return createRadius(0, 0, 0, 0);

            case SegmentBackgroundType.SINGLE_BG:
                return createRadius(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius);

            case SegmentBackgroundType.TOP_LEFT_BG:
                return createRadius(topLeftRadius, 0, 0, 0);

            case SegmentBackgroundType.TOP_LEFT_SINGLE_BG:
                return createRadius(topLeftRadius, 0, 0, bottomLeftRadius);

            case SegmentBackgroundType.TOP_RIGHT_BG:
                return createRadius(0, topRightRadius, 0, 0);

            case SegmentBackgroundType.TOP_RIGHT_SINGLE_BG:
                return createRadius(0, topRightRadius, bottomRightRadius, 0);

            case SegmentBackgroundType.TOP_SINGLE_BG:
                return createRadius(topLeftRadius, topRightRadius, 0, 0);

            default:
                return createRadius(0, 0, 0, 0);
        }
    }

    /**
     * float[]
     *
     * @param topLeft topLeft
     * @param topRight topRight
     * @param bottomRight bottomRight
     * @param bottomLeft bottomLeft
     * @return float[]
     */
    public static float[] createRadius(float topLeft, float topRight, float bottomRight, float bottomLeft) {
        return new float[]{topLeft, topLeft, topRight, topRight, bottomRight, bottomRight, bottomLeft, bottomLeft};
    }

    /**
     * getBackground
     *
     * @param strokeWidth stroke width
     * @param strokeColor stroke color
     * @param argb background color
     * @param radii use {@link #defineRadiusForPosition(int, int, int, int, int, int, int)} method to define radii
     * @return background drawable
     */
    public static ShapeElement getBackground(int strokeWidth, int strokeColor, int argb, float[] radii) {
        ShapeElement drawable = new ShapeElement();
        drawable.setShape(ShapeElement.RECTANGLE);
        drawable.setStroke(strokeWidth, RgbColor.fromArgbInt(strokeColor));
        drawable.setCornerRadiiArray(radii);
        drawable.setRgbColor(RgbColor.fromArgbInt(argb));
        return drawable;
    }

    /**
     * isInBounds
     *
     * @param touchX touchX
     * @param touchY touchY
     * @param viewX viewX
     * @param viewY viewY
     * @param viewW viewW
     * @param viewH viewH
     * @return boolean
     */
    public static boolean isInBounds(double touchX, double touchY, double viewX, double viewY, double viewW, double viewH) {
        return touchX >= viewX && touchX <= viewX + viewW && // in x bounds
                touchY >= viewY && touchY <= viewY + viewH;
    }
}
